"ui";
var install = require("./lib/install.js");
var down = require("./lib/down.js");
var utils = require("./utils");
var monitor = require("./monitor.js");
require("./init");
//阅读app
var readApp = [];
//区块链app
var chainApp = [];
var showui = {};
var floatyWindow;
const common = require("./common");
let run_time_limit = 3600; //默认一个小时
var storage = storages.create("xiangxiangyuedu");
//脚本激活状态
var limit = "未激活";
//当前运行的app
var currentApp = "";
var monitorActivityThread = null;
/**
 * 显示主界面
 */
showui.showMianUi = function () {


    //    events.broadcast.on("CURRENT_INFO", function(msg){
    //         toast("你好, " + name);
    //     });

    ui.layout(
        <drawer id="drawer">
            <vertical>
                <appbar>
                    <appbar>
                        <toolbar w="*" id="toolbar" title="GDT" gravity="center" bg="#008B8B" />

                    </appbar>

                    <Switch id="autoService" text="开启无障碍服务(必须)" checked="{{auto.service != null}}" padding="8 8 8 8" textSize="15sp" bg="#fffffb" />
                    <tabs id="tabs" bg="#008B8B"/>
                </appbar>

                <viewpager id="viewpager" bg="#fffffb">
                    <frame>

                        <ScrollView bg="#fffffb">
                            <vertical>
                                <horizontal>
                                    <checkbox id="转阅任务" text="区块链游戏" textSize="15sp" checked="true" />
                                    <checkbox id="区块链任务" text="执行区块链任务" textSize="15sp" checked="true" />
                                </horizontal>
                                <horizontal>
                                    <checkbox id="休息时间" text="暂停时段" textSize="15sp" checked="true" />
                                    <text text="夜间" textSize="10sp" marginLeft="3sp" />
                                    <input id="起始时间" w="40sp" text="0" inputType="number" />
                                    <text text="点--" textSize="10sp" marginLeft="1sp" />
                                    <input id="结束时间" w="40sp" text="6" inputType="number" />
                                    <text text="点休息" textSize="10sp" marginLeft="1sp" />
                                </horizontal>
                                <horizontal>
                                    <checkbox id="loopExec" text="是否循环运行选中软件" textSize="15sp" checked="true" />
                                </horizontal>
                                <horizontal>
                                    <checkbox id="openConsole" text="是否打开控制台" textSize="15sp" checked="true" />
                                </horizontal>
                                <button id="start" text="任务启动" marginTop="8" textSize="15sp" gravity="center" bg="#008B8B" textColor="#fffffb" />


                            </vertical>
                        </ScrollView>
                    </frame>

                    {/* <!--  自动阅读内容  --> */}
                    <frame>
                        <vertical>

                            <horizontal padding="10" paddingBottom="0">
                                <checkbox id="read_all" hint="全选/全不选" checked="true" />
                            </horizontal>


                            <ScrollView layout_weight="1" padding="2">

                                <vertical>
                                    <list id="listRead">
                                        <card w="*" h="40" margin="2" cardCornerRadius="2dp"
                                            cardElevation="1dp" foreground="?selectableItemBackground">
                                            <horizontal gravity="center_vertical">
                                                <View visibility="{{status==0?'gone':'visible'}}" bg="#ff5722" h="*" w="5" />
                                                <View visibility="{{status==0?'visible':'gone'}}" bg="#119ae8" h="*" w="5" />
                                                <vertical padding="10 8" h="auto" w="0" layout_weight="1">
                                                    <checkbox id="doChecked" checked="{{checked}}" text="{{index+'、'+label}}" textSize="15sp" />
                                                </vertical>

                                                <vertical>
                                                    <button id="doDownload" textColor="{{app.extend.btnTextColor[status]}}" style="Widget.AppCompat.Button.Colored" text="{{app.extend.btnText[status]}}" />
                                                </vertical>

                                            </horizontal>

                                        </card>


                                    </list>
                                </vertical>
                            </ScrollView>


                            <vertical>
                                <button id="install_read_all" style="Widget.AppCompat.Button.Colored" text="全部安装/更新" />
                                {/* <button id="install_test" style="Widget.AppCompat.Button.Colored" text="安装" /> */}
                            </vertical>
                        </vertical>

                    </frame>

                    {/* 区块链 */}
                    <frame>
                        <vertical>
                            <horizontal padding="10" paddingBottom="0">
                                <checkbox id="chain_all" hint="全选/全不选" checked="true" />
                            </horizontal>
                            <ScrollView layout_weight="1" padding="2">
                                <vertical>
                                    <list id="listChain">
                                        <vertical w="*">
                                            <card w="*" h="40" margin="2" cardCornerRadius="2dp"
                                                cardElevation="1dp" foreground="?selectableItemBackground">
                                                <horizontal gravity="center_vertical">
                                                    <View visibility="{{status==0?'gone':'visible'}}" bg="#ff5722" h="*" w="5" />
                                                    <View visibility="{{status==0?'visible':'gone'}}" bg="#119ae8" h="*" w="5" />
                                                    <vertical padding="10 8" h="auto" w="0" layout_weight="1">
                                                        <checkbox id="doChecked" checked="{{checked}}" text="{{index+'、'+label}}" textSize="15sp" />
                                                    </vertical>

                                                    <vertical>
                                                        <button id="doDownload" textColor="{{app.extend.btnTextColor[status]}}" style="Widget.AppCompat.Button.Colored" text="{{app.extend.btnText[status]}}" />
                                                    </vertical>

                                                </horizontal>

                                            </card>

                                        </vertical>
                                    </list>
                                </vertical>
                            </ScrollView>

                            <vertical>
                                <button id="install_chain_all" style="Widget.AppCompat.Button.Colored" text="全部安装/更新" />
                            </vertical>

                        </vertical>
                    </frame>

                </viewpager>
            </vertical>
        </drawer>
    );

    threads.start(function () {
        var storage = storages.create("qdkm");
        var key = storage.get("pass");
        if (key) {
            if(!showui.check(key)){
                var key = rawInput("请输入激活码!");
                if (key && key.length > 0) {
                    var result = showui.check(key);
                    if (!result) {
                        alert("激活码错误");
                        exit();
                    }
                }else{
                    exit();
                }
            }
        }else{
            var key = rawInput("请输入激活码!");
            if (key && key.length > 0) {
                var result = showui.check(key);
                if (!result) {
                    alert("激活码错误");
                    exit();
                }
            }else{
                exit();
            }
        }

    })



    //设置滑动页面的标题
    ui.viewpager.setTitles(["设置", "区块链游戏", "区块链"]);
    //让滑动页面和标签栏联动
    ui.tabs.setupWithViewPager(ui.viewpager);
    //显示控制台
    // console.show();
    //加载列表
    threads.start(function () {

        app.extend.getServerApp(app.extend.all, function (serverApp) {
            ui.post(function () {
                readApp = serverApp.filter(function (item) {
                    return item.type == 1;
                })
                readApp.forEach((item, index) => { item.index = index + 1 });
                ui.listRead.setDataSource(readApp);

                chainApp = serverApp.filter(function (item) {
                    return item.type == 2;
                });

                chainApp.forEach((item, index) => { item.index = index + 1 });
                ui.listChain.setDataSource(chainApp);
            });

        });
    });
    ui.install_chain_all.on("click", function () {


        var _src = chainApp.filter(item => item.status != 0 && item.status != 2);
        if(_src.length == 0){
            toast("没有需要更新的app!");
            return;
        }
        log("dist:", JSON.stringify(_src));
        var src = new java.util.ArrayList();
        _src.forEach(element => {
            src.add(element);
        });
        src = src .toArray();
        var dist = java.lang.reflect.Array.newInstance(java.lang.Object, src.length);
        java.lang.System.arraycopy(src, 0, dist, 0, dist.length);


        threads.start(function(){
            // var arr = chainApp.filter(item => item.status != 0 && item.status != 2);
            // log("dist:", JSON.stringify(dist));
            // return;
            // log("arrlength:", dist.length);
            for(var index in dist){
                let item = dist[index];
                log("正在安装:", item.label);
                utils.downloadAndInstall(item.label, item.url, item.pkg);
                log("正在安装:", JSON.stringify(item));
                // item.status = 0;
                _src[index].status = 0;
                ui.post(function(){
                    ui.listChain.getAdapter().notifyDataSetChanged();
                })

                log("安装结束:", item.label);
            }
           
            log("安装完成");
            toast("安装完成");
        })


        // alert(chainApp.filter(item => item.status != 0).length);

    });
    // ui.install_test.on("click", function(){
    //     console.log("触发点击事件");
    // });
    ui.install_read_all.on("click", function () {
        var _src = readApp.filter(item => item.status != 0 && item.status != 2);
        if(_src.length == 0){
            toast("没有需要更新的app!");
            return;
        }
        var src = new java.util.ArrayList();
        _src.forEach(element => {
            src.add(element);
        });
        src = src .toArray();
        var dist = java.lang.reflect.Array.newInstance(java.lang.Object, src.length);
        java.lang.System.arraycopy(src, 0, dist, 0, dist.length);
        threads.start(function(){
            
            log("arrlength:", src.length);
            for(var index in src){
                var item = src[index];
                utils.downloadAndInstall(item.label, item.url, item.pkg);
                _src[index].status = 0;
                ui.post(function(){
                    ui.listRead.getAdapter().notifyDataSetChanged();
                });
            }
            log("安装完成");
            toast("安装完成");
        })
    });
    ui.listRead.on("item_bind", function (itemView, itemHolder) {
        itemView.doDownload.on("click", function () {
            threads.start(function () {

                let data = itemHolder.item;
                if (data.status == 0) {
                    toast("[" + data.label + "]已经是最新版本");
                    return;
                }
                utils.downloadAndInstall(data.label, data.url, data.pkg);
                data.status = 0;
                
                ui.post(function(){
                    ui.listRead.getAdapter().notifyDataSetChanged();
                })

                
            })
        });
        itemView.doChecked.on("check", function (checked) {
            itemHolder.item.checked = checked;
        });

    })

    ui.chain_all.on("check", function (checked) {

        chainApp.forEach(item => {
            item.checked = checked;
        });
        ui.listChain.getAdapter().notifyDataSetChanged();

    });
    ui.read_all.on("check", function (checked) {

        readApp.forEach(item => {
            item.checked = checked;
        });
        ui.listRead.getAdapter().notifyDataSetChanged();

    });
    ui.listChain.on("item_bind", function (itemView, itemHolder) {
        itemView.doDownload.on("click", function () {
            threads.start(function () {
                let data = itemHolder.item;
                if (data.status == 0) {
                    toast("[" + data.label + "]已经是最新版本");
                    return;
                }
                utils.downloadAndInstall(data.label, data.url, data.pkg);
                data.status = 0;
                ui.post(function(){
                    ui.listChain.getAdapter().notifyDataSetChanged();
                })
                
            });
        });

        itemView.doChecked.on("check", function (checked) {
            itemHolder.item.checked = checked;
        });




    })



    activity.setSupportActionBar(ui.toolbar);
    ui.emitter.on("create_options_menu", menu => {
        menu.add("联众打码");
        menu.add("输入激活码");
    });


    events.broadcast.on(utils.BROADCAST_APP_NAME, function(appName){
        if(floatyWindow){
            ui.run(function(){
                floatyWindow.appName.setText("当前应用:" + appName);
            });
        }
    });
    events.broadcast.on(utils.BROADCAST_APP_PROGRESS, function(progress){
        if(floatyWindow){
            ui.run(function(){
                floatyWindow.cur_progress.setProgress(progress);
            });
        }

    });
    events.broadcast.on(utils.BROADCAST_GLOBAL_PROGRESS, function(progress){
        if(floatyWindow){
            ui.run(function(){
                floatyWindow.total_progress.setProgress(progress);
            });
        }
    });

    //监听选项菜单点击
    ui.emitter.on("options_item_selected", (e, item) => {
        switch (item.getTitle()) {
            case "联众打码":

                break;
            case "输入激活码":
                threads.start(function () {
                    var key = rawInput("请输入激活码!");
                    if (key && key.length > 0) {
                        var result = showui.check(key);
                        if (!result) {
                            alert("激活码错误");
                            exit();
                        }
                    }

                })

                break;

        }
        e.consumed = true;
    });

    events.broadcast.on(monitor.LOCK_ACTIVITY, function(activity){
        if(monitorActivityThread === null){
            monitorActivityThread = threads.start(function(){
                console.log("开始监控 activity:", activity);
                
                while(true){
                    if(currentActivity() !== activity){
                        monitor.alert(activity, currentActivity());
                        //TODO 添加结束标记
                        storage.put("script_running_status", "end");
                        return;
                    }
                    sleep(500);
                }
            });
        }
    });
    events.broadcast.on(monitor.UN_LOCK_ACTIVITY, function(){
        if(monitorActivityThread){
            console.log("停止监控 activity");
            monitorActivityThread.interrupt();
            monitorActivityThread = null;
        }
    });
    //  showui.getkey();
    var storage = storages.create("init");
    storages.remove("applist");
    /**点击启动脚本 */

    ui.autoService.on("check", function (checked) {
        // 用户勾选无障碍服务的选项时，跳转到页面让用户去开启
        if (checked && auto.service == null) {
            app.startActivity({
                action: "android.settings.ACCESSIBILITY_SETTINGS"
            });
        }
        if (!checked && auto.service != null) {
            auto.service.disableSelf();
        }
    });

    // 当用户回到本界面时，resume事件会被触发
    ui.emitter.on("resume", function () {
        // 此时根据无障碍服务的开启情况，同步开关的状态
        ui.autoService.checked = auto.service != null;
    });
    //下载
    threads.start(function () {
        let pjysdk = new PJYSDK("briq0g4o6ite5pmsbvf0", "OniP82K1CvsXxiqAQNR5DSa0CfZ5ZpPj");
        pjysdk.debug = false;
        let ret = pjysdk.GetSoftwareNotice()
        ret = ret.result.notice
        if (ret.length > 1) {
            dialogs.build({
                title: "公告",
                content: ret,
                negative: "确定",
            })
                .show();
        }
    });



    ui.start.on("click", function () {

        var storage = storages.create("qdkm");
        var key = storage.get("pass");
        if (!key) {
            alert("请先输入激活码");
            return;
        }
        /**启动线程脚本 */
        toastLog("开启");

        threads.start(
            function () {
                auto.waitFor()
                toast('权限获取完成！继续运行')
                // sleep(1000);
                // showui.验证();
                sleep(3000);
                console.time("总耗时");
                if(!floatyWindow){
                    floatyWindow = floaty.rawWindow(
                        <vertical bg="#cccccccc" padding="0 5" radius="5">
                          <text id="appName" textColor="black" textSize="10sp" margin="8" text="当前应用:无" />
                          <text id="runTime" textColor="black" textSize="10sp" margin="8" text="已运行时间:0秒" />
                      
                          <horizontal gravity="center">
                            <text textColor="black" textSize="10sp" margin="8" text="当前进度" />
                            <progressbar progress="0" id="cur_progress" w="*" max="100" style="@style/Base.Widget.AppCompat.ProgressBar.Horizontal" />
                          </horizontal>
                          <horizontal gravity="center">
                            <text textColor="black" textSize="10sp" margin="8" text="总进度    " />
                            <progressbar progress="0" id="total_progress" w="*" max="100" style="@style/Base.Widget.AppCompat.ProgressBar.Horizontal" />
                          </horizontal>
                        </vertical>
                      );
                      floatyWindow.exitOnClose();
                      floatyWindow.setSize(-1, -2);
                      floatyWindow.setPosition(0, 0)
                      floatyWindow.setTouchable(false);
                }
                var start = java.lang.System.currentTimeMillis();
                var intervalId=0;
                threads.start(function(){
                    intervalId= setInterval(()=>{
                        if(floatyWindow){
                            floatyWindow.runTime.setText("已运行时间:" + parseInt((java.lang.System.currentTimeMillis() - start) / 1000) + "秒");
                        }
                    }, 1000);
                });
                try {
                  
                    showui.run();
                }finally{
                    intervalId && clearInterval(intervalId)
                }
                console.timeEnd("总耗时");
            });
    });

    //控制台
    ui.openConsole.on("click", function () {
        log('控制台');
        ui.openConsole.isChecked()?console.show():console.hide();
    });

    // ui.jiebang.on("click", function () {
    //     showui.解除();
    // });

}


showui.cheak = function () {
    toast('卡密校验开始，请稍等')
    cradpassword = ui.cradpassword.text();
    var storage = storages.create("qdkm");
    if (cradpassword != null && cradpassword.length == 32) {
        sleep(1000);
        showui.yy_login(cradpassword);
    } else if (storage.contains("pass")) {
        cradpassword = storage.get("pass")//尝试从本地文件读取卡密
        if (cradpassword.length != 32) {
            toastLog('本地存储卡密校验失败');
        } else {
            toastLog('本地卡密存在');
            showui.yy_login(cradpassword);
        }
    } else {
        toastLog('本地卡密不存在，且未输入卡密！2s后结束运行！');
        sleep(2000);
        exit();
    }
}
showui.yy_login = function (password) {
    var Ver = '1.0.1'
    var storage = storages.create("qdkm");
    var login_url = 'http://w.eydata.net/adaf45e734f37ff0' //易游单码登录地址
    var time_url = 'http://w.eydata.net/f990cd237d7209a7'
    var herat = '' //心跳验证地址
    var code = null //状态码
    var data = null
    code = http.post(login_url, {
        'SingleCode': password,
        'Ver': Ver,
        'Mac': device.getAndroidId() // 设备imei
    })
    if (code.body.string().length != 32) {
        //console.log(code.body.string())
        toastLog('卡密失效！请联系管理员！');
        sleep(2000);
        exit();
    } else {
        data = http.post(time_url, {
            'UserName': password,
        })
        toastLog("验证完成！");
        sleep(1000);
        toastLog("到期时间:" + data.body.string());
        storage.put("pass", cradpassword)
    };
}


showui.run = function () {
    var apps = [];
    if (ui.区块链任务.isChecked()) {
        chainApp.filter(item => item.checked).forEach(item => apps.push(item.label))
    }
    if (ui.转阅任务.isChecked()) {
        readApp.filter(item => item.checked).forEach(item => apps.push(item.label))
    }
    if (!apps || apps.length == 0) {
        toastLog("没有选择APP或不予执行选中任务");
        return;
    }
    var qstime = ui.起始时间.text();
    var jstime = ui.结束时间.text();
    do {
        var nowtime = new Date().getHours();
        bls = showui.boools(qstime, jstime, nowtime);
        if (!bls) {
            toast("非运行时间.")
            utils.updateAppName("非运行时间");
            common.clears();
            sleep(60 * 1000)
            return ;
            
        }
       
        for (var i = 0; i < apps.length; i++) {
            log("前task - " + engines.all().length);
            while (engines.all().length > 1) {
                sleep(5000);
            }
            nowtime = new Date().getHours();
            bls = showui.boools(qstime, jstime, nowtime);
            if (!bls) {
                toast("非运行时间.")
                common.clears();
                break;
            }

            storage.put("script_running_status", "running");
            log("engines " + apps[i] + ".js");
            toastLog("开始运行:"+apps[i]);
            console.time(apps[i]);
            try {
                utils.updateAppName(apps[i]);
                utils.updateGlobalProgress((i / apps.length) * 100);
                utils.updateAppProgress(0);
                utils.download_scripts(apps[i]);
                engines_execscript = engines.execScriptFile("./" + apps[i] + ".js");
                currentApp = apps[i];
                log(currentApp + " - 已经在执行中了")
            } catch (e) {
                storage.put("script_running_status", "end");
            }
            script_wait(engines_execscript, run_time_limit);
            console.timeEnd(apps[i]);
            if(monitorActivityThread){
                monitorActivityThread.interrupt();
                monitorActivityThread = null;
            }
            common.clears(); //恢复
        }
        currentApp = "";
    } while (ui.loopExec.isChecked());
    
}



function script_wait(e, run_time_limit) {
    //限制脚本运行时间, 配置时间内脚本没有运行完，则强制停止运行脚本
    let stop_count = run_time_limit * 1000 / 10000;
    log("stop_count: ", stop_count);
    let count = 0;
    while (count < stop_count) {
        log("check script wither running ... " + (count + 1));
        let script_running_status = storage.get("script_running_status");
        if (script_running_status == "running") {
            sleep(20000);
            count++;
        }
        else {
            log("checked script running end ...")
            e.getEngine().forceStop();
            return;
        }
    }
    if (count == stop_count) {
        log("脚本运行超过了" + run_time_limit + "秒，强行停止！")
        e.getEngine().forceStop();
        storage.put("script_running_status", "end");
    }

}
showui.重置 = function () {
    log("重置初始")
    let storage = storages.create("init");
    storage.clear();
}
showui.suijipx = function (arr) {
    for (i = arr.length - 1; i > 0; i--) {
        let j = Math.floor(Math.random() * (i + 1));
        [arr[i], arr[j]] = [arr[j], arr[i]];//es6 写法
    }
    return arr;
}

showui.boools = function (x, y, z) {
    x = parseInt(x);
    y = parseInt(y);
    z = parseInt(z);
    if (x > y) {

        if (z < y || z > x) {
            return false;
        } else {
            return true;
        }
    } else {

        if (z > x && z < y) {
            return false;
        } else {
            return true;
        }
    }


}



showui.check = function (key) {
    // toastLog(current_ver);
    // var checkkey = ui.checkkey.text()
    // AppKey 和 AppSecret 在泡椒云开发者后台获取
    // let pjysdk = new PJYSDK("briq0g4o6ite5pmsbvf0", "OniP82K1CvsXxiqAQNR5DSa0CfZ5ZpPj");
    let pjysdk = new PJYSDK("btdiv0co6itf6872fup0", "0x5TYjhgpGXQoRaLhjlk3wrgprlKtN5e");
    pjysdk.debug = false;
    pjysdk.SetCard(key);

    // 监听心跳失败事件
    pjysdk.event.on("heartbeat_failed", function (hret) {
        toastLog(hret.message);  // 失败提示信息
        exit();  // 退出脚本
    })
    let login_ret = pjysdk.CardLogin();
    let shenyutime = pjysdk.GetTimeRemaining();

    if (login_ret.code == 0) {
        // 登录成功，后面写你的业务代码
        toastLog("剩余时间:" + parseInt(shenyutime / 60 / 60 / 24) + "天")

        limit = parseInt(shenyutime / 60 / 60 / 24) + "天";
        ui.post(function(){
            ui.toolbar.setTitle("GDT(剩余:" + limit + ")");
        });
        var storage = storages.create("qdkm");
        storage.put("pass", key)
        return true;
    } else {
        // 登录失败提示
        limit = login_ret.message;
        ui.post(function(){
            ui.toolbar.setTitle("GDT(" + limit + ")");
        });
        toastLog(login_ret.message);
        return false;
        // sleep(3000);
        //    exit();
    }

    // // 用户主动退出时记得调用logout
    // pjysdk.CardLogout();
}



showui.验证 = function () {

    // toastLog(current_ver);
    var checkkey = ui.checkkey.text()
    // AppKey 和 AppSecret 在泡椒云开发者后台获取
    // let pjysdk = new PJYSDK("briq0g4o6ite5pmsbvf0", "OniP82K1CvsXxiqAQNR5DSa0CfZ5ZpPj");
    let pjysdk = new PJYSDK("btdiv0co6itf6872fup0", "0x5TYjhgpGXQoRaLhjlk3wrgprlKtN5e");
    pjysdk.debug = false;
    pjysdk.SetCard(checkkey);

    // 监听心跳失败事件
    pjysdk.event.on("heartbeat_failed", function (hret) {
        toastLog(hret.message);  // 失败提示信息
        exit();  // 退出脚本
    })
    let login_ret = pjysdk.CardLogin();
    let shenyutime = pjysdk.GetTimeRemaining();
    if (login_ret.code == 0) {
        // 登录成功，后面写你的业务代码
        toastLog("剩余时间:" + parseInt(shenyutime / 60 / 60 / 24) + "天")
        var storage = storages.create("qdkm");
        storage.put("pass", checkkey)

    } else {
        // 登录失败提示
        toastLog(login_ret.message);
        sleep(3000);
        exit();
    }

    // // 用户主动退出时记得调用logout
    // pjysdk.CardLogout();
}


showui.解除 = function () {
    let pjysdk = new PJYSDK("btdiv0co6itf6872fup0", "0x5TYjhgpGXQoRaLhjlk3wrgprlKtN5e");
    // 用户主动退出时记得调用logout
    let jie = pjysdk.CardLogout();
    if (jie.code == 0) {
        // 登录成功，后面写你的业务代码
        toastLog("解绑成功")
    } else {
        // 登录失败提示
        toastLog("出了点小问题")
    }
}
const PJYSDK = (function () {
    function PJYSDK(app_key, app_secret) {
        http.__okhttp__.setMaxRetries(0);

        this.event = events.emitter();

        this.debug = true;
        this._lib_version = "v1.01";
        this._protocol = "https";
        this._host = "api.paojiaoyun.com";
        this._device_id = this.getDeviceID();

        this._app_key = app_key;  // AppKey，在开发者后台获取
        this._app_secret = app_secret;  // AppScret，在开发者后获取

        this._card = null;
        this._username = null;
        this._password = null;
        this._token = null;

        this.is_trial = false;  // 是否是试用用户
        this.login_result = {
            "card_type": "",
            "expires": "",
            "expires_ts": 0,
            "config": "",
        };

        this._auto_heartbeat = true;  // 是否自动开启心跳任务
        this._heartbeat_gap = 60 * 1000; // 默认60秒
        this._heartbeat_task = null;
        this._heartbeat_ret = { "code": -9, "message": "还未开始验证" };

        this._prev_nonce = null;
    }
    PJYSDK.prototype.SetCard = function (card) {
        this._card = card;
    }
    PJYSDK.prototype.SetUser = function (username, password) {
        this._username = username;
        this._password = password;
    }
    PJYSDK.prototype.getDeviceID = function () {
        let id = device.serial;
        if (id == "") {
            id = device.getIMEI();
        }
        return id;
    }
    PJYSDK.prototype.MD5 = function (str) {
        try {
            let digest = java.security.MessageDigest.getInstance("md5");
            let result = digest.digest(new java.lang.String(str).getBytes("UTF-8"));
            let buffer = new java.lang.StringBuffer();
            for (let index = 0; index < result.length; index++) {
                let b = result[index];
                let number = b & 0xff;
                let str = java.lang.Integer.toHexString(number);
                if (str.length == 1) {
                    buffer.append("0");
                }
                buffer.append(str);
            }
            return buffer.toString();
        } catch (error) {
            alert(error);
            return "";
        }
    }
    PJYSDK.prototype.getTimestamp = function () {
        try {
            let res = http.get("http://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp");
            let data = res.body.json();
            return Math.floor(data["data"]["t"] / 1000);
        } catch (error) {
            return Math.floor(new Date().getTime() / 1000);
        }
    }
    PJYSDK.prototype.genNonce = function () {
        const ascii_str = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
        let tmp = '';
        for (let i = 0; i < 20; i++) {
            tmp += ascii_str.charAt(Math.round(Math.random() * ascii_str.length));
        }
        return tmp;
    }
    PJYSDK.prototype.joinParams = function (params) {
        let ps = [];
        for (let k in params) {
            ps.push(k + "=" + params[k])
        }
        ps.sort()
        return ps.join("&")
    }
    PJYSDK.prototype.CheckRespSign = function (resp) {
        let ps = "";
        if (resp["result"]) {
            ps = this.joinParams(resp["result"]);
        }

        let s = resp["code"] + resp["message"] + ps + resp["nonce"] + this._app_secret;
        let sign = this.MD5(s);
        if (sign === resp["sign"]) {
            if (this._prev_nonce === null) {
                this._prev_nonce = resp["nonce"];
                return { "code": 0, "message": "OK" };
            } else {
                if (this._prev_nonce === resp["nonce"]) {
                    return { "code": -98, "message": "轻点，疼~" };
                } else {
                    return { "code": 0, "message": "OK" };
                }
            }
        }
        return { "code": -99, "message": "轻点，疼~" };
    }
    PJYSDK.prototype._debug = function (path, params, result) {
        if (this.debug) {
            log("\n" + path, "\nparams:", params, "\nresult:", result);
        }
    }
    PJYSDK.prototype.Request = function (method, path, params) {
        // 构建公共参数
        params["app_key"] = this._app_key;
        params["nonce"] = this.genNonce();
        params["timestamp"] = this.getTimestamp();

        method = method.toUpperCase();
        let url = this._protocol + "://" + this._host + path
        let max_retries = 5;
        let retries_count = 0;

        let ps = this.joinParams(params);
        let s = method + this._host + path + ps + this._app_secret;

        let sign = this.MD5(s);
        params["sign"] = sign;

        let data = { "code": -1, "message": "连接服务器失败" };
        do {
            retries_count++;

            let resp, body;
            try {
                if (method === "GET") {
                    resp = http.get(url + "?" + ps + "&sign=" + sign);
                } else {  // POST
                    resp = http.post(url, params);
                }
                body = resp.body.string();
                data = JSON.parse(body);
                this._debug(method + '-' + path + ':', params, data);

                let crs = this.CheckRespSign(data);
                if (crs.code !== 0) {
                    return crs;
                } else {
                    return data;
                }
            } catch (error) {
                log("[*] request error: ", error);
                this._debug(method + '-' + path + ':', params, body)
                sleep(1000);
            }
        } while (retries_count < max_retries);

        return data;
    }
    /* 通用 */
    PJYSDK.prototype.GetHeartbeatResult = function () {
        return this._heartbeat_ret;
    }
    PJYSDK.prototype.GetTimeRemaining = function () {
        let g = this.login_result.expires_ts - this.getTimestamp();
        if (g < 0) {
            return 0;
        }
        return g;
    }
    /* 卡密相关 */
    PJYSDK.prototype.CardLogin = function () {  // 卡密登录
        if (!this._card) {
            return { "code": -4, "message": "请先设置卡密" };
        }
        if (this._token) {
            return { "code": -3, "message": "请先退出登录" };
        }
        let method = "POST";
        let path = "/v1/card/login";
        let data = { "card": this._card, "device_id": this._device_id };
        let ret = this.Request(method, path, data);
        if (ret.code == 0) {
            this._token = ret.result.token;
            this.login_result = ret.result;
            // if (this._auto_heartbeat) {
            //     this._startCardHeartheat();
            // }
        }
        return ret;
    }
    PJYSDK.prototype.CardHeartbeat = function () {  // 卡密心跳，默认会自动调用
        if (!this._token) {
            return { "code": -2, "message": "请在卡密登录成功后调用" };
        }
        let method = "POST";
        let path = "/v1/card/heartbeat";
        let data = { "card": this._card, "token": this._token };
        let ret = this.Request(method, path, data);
        if (ret.code == 0) {
            this.login_result.expires = ret.result.expires;
            this.login_result.expires_ts = ret.result.expires_ts;
        }
        return ret;
    }
    PJYSDK.prototype._startCardHeartheat = function () {  // 开启卡密心跳任务
        if (this._heartbeat_task) {
            this._heartbeat_task.interrupt();
            this._heartbeat_task = null;
        }
        this._heartbeat_task = threads.start(function () {
            setInterval(function () { }, 10000);
        });
        this._heartbeat_ret = this.CardHeartbeat();

        this._heartbeat_task.setInterval((self) => {
            self._heartbeat_ret = self.CardHeartbeat();
            if (self._heartbeat_ret.code != 0) {
                self.event.emit("heartbeat_failed", self._heartbeat_ret);
            }
        }, this._heartbeat_gap, this);

        this._heartbeat_task.setInterval((self) => {
            if (self.GetTimeRemaining() == 0) {
                self.event.emit("heartbeat_failed", { "code": 10210, "message": "卡密已过期！" });
            }
        }, 1000, this);
    }
    PJYSDK.prototype.CardLogout = function () {  // 卡密退出登录
        this._heartbeat_ret = { "code": -9, "message": "还未开始验证" };
        if (this._heartbeat_task) { // 结束心跳任务
            this._heartbeat_task.interrupt();
            this._heartbeat_task = null;
        }
        if (!this._token) {
            return { "code": 0, "message": "OK" };
        }
        let method = "POST";
        let path = "/v1/card/logout";
        let data = { "card": this._card, "token": this._token };
        let ret = this.Request(method, path, data);
        // 清理
        this._token = null;
        this.login_result = {
            "card_type": "",
            "expires": "",
            "expires_ts": 0,
            "config": "",
        };
        return ret;
    }
    PJYSDK.prototype.CardUnbindDevice = function () { // 卡密解绑设备，需开发者后台配置
        if (!this._token) {
            return { "code": -2, "message": "请在卡密登录成功后调用" };
        }
        let method = "POST";
        let path = "/v1/card/unbind_device";
        let data = { "card": this._card, "device_id": this._device_id, "token": this._token };
        return this.Request(method, path, data);
    }
    PJYSDK.prototype.SetCardUnbindPassword = function (password) { // 自定义设置解绑密码
        if (!this._token) {
            return { "code": -2, "message": "请在卡密登录成功后调用" };
        }
        let method = "POST";
        let path = "/v1/card/unbind_password";
        let data = { "card": this._card, "password": password, "token": this._token };
        return this.Request(method, path, data);
    }
    PJYSDK.prototype.CardUnbindDeviceByPassword = function (password) { // 用户通过解绑密码解绑设备
        let method = "POST";
        let path = "/v1/card/unbind_device/by_password";
        let data = { "card": this._card, "password": password };
        return this.Request(method, path, data);
    }
    /* 用户相关 */
    PJYSDK.prototype.UserRegister = function (username, password, card) {  // 用户注册（通过卡密）
        let method = "POST";
        let path = "/v1/user/register";
        let data = { "username": username, "password": password, "card": card, "device_id": this._device_id };
        return this.Request(method, path, data);
    }
    PJYSDK.prototype.UserLogin = function () {  // 用户账号登录
        if (!this._username || !this._password) {
            return { "code": -4, "message": "请先设置用户账号密码" };
        }
        if (this._token) {
            return { "code": -3, "message": "请先退出登录" };
        }
        let method = "POST";
        let path = "/v1/user/login";
        let data = { "username": this._username, "password": this._password, "device_id": this._device_id };
        let ret = this.Request(method, path, data);
        if (ret.code == 0) {
            this._token = ret.result.token;
            this.login_result = ret.result;
            if (this._auto_heartbeat) {
                this._startUserHeartheat();
            }
        }
        return ret;
    }
    PJYSDK.prototype.UserHeartbeat = function () {  // 用户心跳，默认会自动开启
        if (!this._token) {
            return { "code": -2, "message": "请在用户登录成功后调用" };
        }
        let method = "POST";
        let path = "/v1/user/heartbeat";
        let data = { "username": this._username, "token": this._token };
        let ret = this.Request(method, path, data);
        if (ret.code == 0) {
            this.login_result.expires = ret.result.expires;
            this.login_result.expires_ts = ret.result.expires_ts;
        }
        return ret;
    }
    PJYSDK.prototype._startUserHeartheat = function () {  // 开启用户心跳任务
        if (this._heartbeat_task) {
            this._heartbeat_task.interrupt();
            this._heartbeat_task = null;
        }
        this._heartbeat_task = threads.start(function () {
            setInterval(function () { }, 10000);
        });
        this._heartbeat_ret = this.UserHeartbeat();

        this._heartbeat_task.setInterval((self) => {
            self._heartbeat_ret = self.UserHeartbeat();
            if (self._heartbeat_ret.code != 0) {
                self.event.emit("heartbeat_failed", self._heartbeat_ret);
            }
        }, this._heartbeat_gap, this);

        this._heartbeat_task.setInterval((self) => {
            if (self.GetTimeRemaining() == 0) {
                self.event.emit("heartbeat_failed", { "code": 10250, "message": "用户已到期！" });
            }
        }, 1000, this);
    }
    PJYSDK.prototype.UserLogout = function () {  // 用户退出登录
        this._heartbeat_ret = { "code": -9, "message": "还未开始验证" };
        if (this._heartbeat_task) { // 结束心跳任务
            this._heartbeat_task.interrupt();
            this._heartbeat_task = null;
        }
        if (!this._token) {
            return { "code": 0, "message": "OK" };
        }
        let method = "POST";
        let path = "/v1/user/logout";
        let data = { "username": this._username, "token": this._token };
        let ret = this.Request(method, path, data);
        // 清理
        this._token = null;
        this.login_result = {
            "card_type": "",
            "expires": "",
            "expires_ts": 0,
            "config": "",
        };
        return ret;
    }
    PJYSDK.prototype.UserChangePassword = function (username, password, new_password) {  // 用户修改密码
        let method = "POST";
        let path = "/v1/user/password";
        let data = { "username": username, "password": password, "new_password": new_password };
        return this.Request(method, path, data);
    }
    PJYSDK.prototype.UserRecharge = function (username, card) { // 用户通过卡密充值
        let method = "POST";
        let path = "/v1/user/recharge";
        let data = { "username": username, "card": card };
        return this.Request(method, path, data);
    }
    PJYSDK.prototype.UserUnbindDevice = function () { // 用户解绑设备，需开发者后台配置
        if (!this._token) {
            return { "code": -2, "message": "请在用户登录成功后调用" };
        }
        let method = "POST";
        let path = "/v1/user/unbind_device";
        let data = { "username": this._username, "device_id": this._device_id, "token": this._token };
        return this.Request(method, path, data);
    }
    /* 配置相关 */
    PJYSDK.prototype.GetCardConfig = function () { // 获取卡密配置
        let method = "GET";
        let path = "/v1/card/config";
        let data = { "card": this._card };
        return this.Request(method, path, data);
    }
    PJYSDK.prototype.UpdateCardConfig = function (config) { // 更新卡密配置
        let method = "POST";
        let path = "/v1/card/config";
        let data = { "card": this._card, "config": config };
        return this.Request(method, path, data);
    }
    PJYSDK.prototype.GetUserConfig = function () { // 获取用户配置
        let method = "GET";
        let path = "/v1/user/config";
        let data = { "user": this._username };
        return this.Request(method, path, data);
    }
    PJYSDK.prototype.UpdateUserConfig = function (config) { // 更新用户配置
        let method = "POST";
        let path = "/v1/user/config";
        let data = { "username": this._username, "config": config };
        return this.Request(method, path, data);
    }
    /* 软件相关 */
    PJYSDK.prototype.GetSoftwareConfig = function () { // 获取软件配置
        let method = "GET";
        let path = "/v1/software/config";
        return this.Request(method, path, {});
    }
    PJYSDK.prototype.GetSoftwareNotice = function () { // 获取软件通知
        let method = "GET";
        let path = "/v1/software/notice";
        return this.Request(method, path, {});
    }
    PJYSDK.prototype.GetSoftwareLatestVersion = function (current_ver) { // 获取软件最新版本
        let method = "GET";
        let path = "/v1/software/latest_ver";
        let data = { "version": current_ver };
        return this.Request(method, path, data);
    }
    /* 试用功能 */
    PJYSDK.prototype.TrialLogin = function () {  // 试用登录
        let method = "POST";
        let path = "/v1/trial/login";
        let data = { "device_id": this._device_id };
        let ret = this.Request(method, path, data);
        if (ret.code == 0) {
            this.is_trial = true;
            this.login_result = ret.result;
            if (this._auto_heartbeat) {
                this._startTrialHeartheat();
            }
        }
        return ret;
    }
    PJYSDK.prototype.TrialHeartbeat = function () {  // 试用心跳，默认会自动调用
        let method = "POST";
        let path = "/v1/trial/heartbeat";
        let data = { "device_id": this._device_id };
        let ret = this.Request(method, path, data);
        if (ret.code == 0) {
            this.login_result.expires = ret.result.expires;
            this.login_result.expires_ts = ret.result.expires_ts;
        }
        return ret;
    }
    PJYSDK.prototype._startTrialHeartheat = function () {  // 开启试用心跳任务
        if (this._heartbeat_task) {
            this._heartbeat_task.interrupt();
            this._heartbeat_task = null;
        }
        this._heartbeat_task = threads.start(function () {
            setInterval(function () { }, 10000);
        });
        this._heartbeat_ret = this.TrialHeartbeat();

        this._heartbeat_task.setInterval((self) => {
            self._heartbeat_ret = self.CardHeartbeat();
            if (self._heartbeat_ret.code != 0) {
                self.event.emit("heartbeat_failed", self._heartbeat_ret);
            }
        }, this._heartbeat_gap, this);

        this._heartbeat_task.setInterval((self) => {
            if (self.GetTimeRemaining() == 0) {
                self.event.emit("heartbeat_failed", { "code": 10407, "message": "试用已到期！" });
            }
        }, 1000, this);
    }
    PJYSDK.prototype.TrialLogout = function () {  // 试用退出登录，没有http请求，只是清理本地记录
        this.is_trial = false;
        this._heartbeat_ret = { "code": -9, "message": "还未开始验证" };
        if (this._heartbeat_task) { // 结束心跳任务
            this._heartbeat_task.interrupt();
            this._heartbeat_task = null;
        }
        // 清理
        this._token = null;
        this.login_result = {
            "card_type": "",
            "expires": "",
            "expires_ts": 0,
            "config": "",
        };
        return { "code": 0, "message": "OK" };;
    }
    /* 高级功能 */
    PJYSDK.prototype.GetRemoteVar = function (key) { // 获取远程变量
        let method = "GET";
        let path = "/v1/af/remote_var";
        let data = { "key": key };
        return this.Request(method, path, data);
    }
    PJYSDK.prototype.GetRemoteData = function (key) { // 获取远程数据
        let method = "GET";
        let path = "/v1/af/remote_data";
        let data = { "key": key };
        return this.Request(method, path, data);
    }
    PJYSDK.prototype.CreateRemoteData = function (key, value) { // 创建远程数据
        let method = "POST";
        let path = "/v1/af/remote_data";
        let data = { "action": "create", "key": key, "value": value };
        return this.Request(method, path, data);
    }
    PJYSDK.prototype.UpdateRemoteData = function (key, value) { // 修改远程数据
        let method = "POST";
        let path = "/v1/af/remote_data";
        let data = { "action": "update", "key": key, "value": value };
        return this.Request(method, path, data);
    }
    PJYSDK.prototype.DeleteRemoteData = function (key, value) { // 删除远程数据
        let method = "POST";
        let path = "/v1/af/remote_data";
        let data = { "action": "delete", "key": key };
        return this.Request(method, path, data);
    }
    PJYSDK.prototype.CallRemoteFunc = function (func_name, params) { // 执行远程函数
        let method = "POST";
        let path = "/v1/af/call_remote_func";
        let ps = JSON.stringify(params);
        let data = { "func_name": func_name, "params": ps };
        let ret = this.Request(method, path, data);
        if (ret.code == 0 && ret.result.return) {
            ret.result = JSON.parse(ret.result.return);
        }
        return ret;
    }
    return PJYSDK;
})();
module.exports = showui;